package com.example.config.resp;

import java.io.IOException;
import java.math.BigDecimal;
import java.util.Collection;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.BeanProperty;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializationConfig;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.DefaultSerializerProvider;
import com.fasterxml.jackson.databind.ser.SerializerFactory;

public class CustomSerializerProvider extends DefaultSerializerProvider {

	private static final long serialVersionUID = 1L;

	public CustomSerializerProvider() {
		super();
	}

	public CustomSerializerProvider(SerializerProvider src, SerializationConfig config, SerializerFactory f) {
		super(src, config, f);
	}

	public CustomSerializerProvider(DefaultSerializerProvider src) {
		super(src);
	}

	@Override
	public DefaultSerializerProvider createInstance(SerializationConfig arg0, SerializerFactory arg1) {
		return new CustomSerializerProvider(this, arg0, arg1);
	}
	
	@Override
	public JsonSerializer<Object> findNullValueSerializer(BeanProperty property) throws JsonMappingException {
		if(String.class.isAssignableFrom(property.getType().getRawClass())){
			return NullStringSerializer.INSTANCE;
		}
		if(Collection.class.isAssignableFrom(property.getType().getRawClass())){
			return NullListSerializer.INSTANCE;
		}
		if(BigDecimal.class.isAssignableFrom(property.getType().getRawClass())){
			return NullBigDecimalSerializer.INSTANCE;
		}
		if(Object.class.isAssignableFrom(property.getType().getRawClass())){
			return NullObjectSerializer.INSTANCE;
		}
		return super.findNullValueSerializer(property);
	}
	

	public static class NullStringSerializer extends JsonSerializer<Object> {
		
		public final static JsonSerializer<Object> INSTANCE = new NullStringSerializer();
		
		private NullStringSerializer() {}
		
		public void serialize(Object value, JsonGenerator jgen, SerializerProvider provider)
				throws IOException, JsonProcessingException {
			jgen.writeString("");
		}
	}
	
	public static class NullListSerializer extends JsonSerializer<Object> {
		
		public final static JsonSerializer<Object> INSTANCE = new NullListSerializer();
		
		private NullListSerializer() {}
		
		public void serialize(Object value, JsonGenerator jgen, SerializerProvider provider)
				throws IOException, JsonProcessingException {
			jgen.writeString("[]");
		}
	}
	
	public static class NullBigDecimalSerializer extends JsonSerializer<Object> {
		
		public final static JsonSerializer<Object> INSTANCE = new NullBigDecimalSerializer();
		
		private NullBigDecimalSerializer() {}
		
		public void serialize(Object value, JsonGenerator jgen, SerializerProvider provider)
				throws IOException, JsonProcessingException {
			jgen.writeString("0");
		}
	}
	
	public static class NullObjectSerializer extends JsonSerializer<Object> {
		
		public final static JsonSerializer<Object> INSTANCE = new NullObjectSerializer();
		
		private NullObjectSerializer() {}
		
		public void serialize(Object value, JsonGenerator jgen, SerializerProvider provider)
				throws IOException, JsonProcessingException {
			jgen.writeString("{}");
		}
	}
	
}
